import json
import logging
import requests
import os
import time
from datetime import datetime
import xbot
from xbot import print, sleep
# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.StreamHandler(),
        logging.FileHandler('dify_workflow.log', encoding='utf-8')
    ]
)
logger = logging.getLogger(__name__)

def process_file(file_path: str = "F:\\下载\\合同2.pdf", user: str = "default_user") -> str:
    """
    处理文件并返回工作流执行结果
    
    Args:
        file_path: 文件路径，默认为F:\\下载\\合同2.pdf
        user: 用户标识
        
    Returns:
        JSON字符串形式的执行结果
    """
    start_time = time.time()
    print(f"开始处理文件: {file_path}")
    
    try:
        # 配置
        config = {
            "api_key": "app-z81zqxyf7Fe5LeL6vx6shhx9",
            "base_url": "http://localhost/v1"
        }
        
        # 上传文件
        upload_start = time.time()
        file_id = upload_file(file_path, user, config)
        upload_time = time.time() - upload_start
        print(f"文件上传耗时: {upload_time:.2f}秒")
        
        if not file_id:
            return json.dumps({
                "status": "error",
                "message": "文件上传失败",
                "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "execution_time": time.time() - start_time
            }, ensure_ascii=False)
            
        # 执行工作流（带重试机制）
        max_retries = 3
        retry_count = 0
        workflow_start = time.time()
        
        while retry_count < max_retries:
            result = run_workflow(file_id, user, config)
            workflow_time = time.time() - workflow_start
            
            # 检查结果中是否包含合同编号
            if isinstance(result, dict) and "data" in result:
                try:
                    # 尝试解析工作流输出中的JSON
                    outputs = result["data"]["outputs"]
                    if "text" in outputs:
                        text_content = outputs["text"].replace("```json", "").replace("```", "")
                        parsed_result = json.loads(text_content)
                        
                        # 检查是否包含合同编号
                        if "合同编号" in parsed_result and parsed_result["合同编号"] is not None:
                            print(f"工作流执行成功，包含合同编号")
                            break
                        else:
                            print(f"第{retry_count + 1}次执行未获取到合同编号，准备重试...")
                            retry_count += 1
                            if retry_count < max_retries:
                                time.sleep(2)  # 等待2秒后重试
                            continue
                except json.JSONDecodeError:
                    print(f"第{retry_count + 1}次执行结果解析失败，准备重试...")
                    retry_count += 1
                    if retry_count < max_retries:
                        time.sleep(2)
                    continue
            
            print(f"第{retry_count + 1}次执行未获取到有效结果，准备重试...")
            retry_count += 1
            if retry_count < max_retries:
                time.sleep(2)
        
        if retry_count >= max_retries:
            print("达到最大重试次数，返回最后一次执行结果")
        
        # 添加执行时间信息
        if isinstance(result, dict):
            result.update({
                "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "execution_time": {
                    "total": time.time() - start_time,
                    "upload": upload_time,
                    "workflow": workflow_time,
                    "retry_count": retry_count
                }
            })
        
        return json.dumps(result, ensure_ascii=False, indent=2)
        
    except Exception as e:
        error_msg = f"处理文件时发生错误: {str(e)}"
        print(error_msg)
        return json.dumps({
            "status": "error",
            "message": error_msg,
            "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "execution_time": time.time() - start_time
        }, ensure_ascii=False, indent=2)

def upload_file(file_path: str, user: str, config: dict) -> str:
    """上传文件到Dify服务器"""
    try:
        print("开始上传文件...")
        
        if not os.path.exists(file_path):
            print(f"文件不存在: {file_path}")
            return None
            
        url = f"{config['base_url']}/files/upload"
        headers = {
            "Authorization": f"Bearer {config['api_key']}"
        }
        
        # 获取文件类型
        ext = os.path.splitext(file_path)[1].lower()
        mime_type = 'application/pdf' if ext == '.pdf' else 'text/plain'
        file_type = 'document'
        
        with open(file_path, 'rb') as file:
            files = {
                'file': (os.path.basename(file_path), file, mime_type)
            }
            data = {
                "user": user,
                "type": file_type
            }
            
            response = requests.post(url, headers=headers, files=files, data=data)
            
            if response.status_code == 201:
                file_id = response.json().get("id")
                print(f"文件上传成功，ID: {file_id}")
                return file_id
            else:
                print(f"文件上传失败，状态码: {response.status_code}")
                if hasattr(response, 'outputs'):
                    print(f"错误详情: {response.text}")
                return None
                
    except Exception as e:
        print(f"上传文件时发生错误: {str(e)}")
        return None

def run_workflow(file_id: str, user: str, config: dict) -> dict:
    """执行Dify工作流"""
    try:
        print("开始执行工作流...")
        
        url = f"{config['base_url']}/workflows/run"
        headers = {
            "Authorization": f"Bearer {config['api_key']}",
            "Content-Type": "application/json"
        }
        
        data = {
            "inputs": {
                "contract": {
                    "transfer_method": "local_file",
                    "upload_file_id": file_id,
                    "type": "document"
                }
            },
            "response_mode": "blocking",
            "user": user
        }
        
        response = requests.post(url, headers=headers, json=data)
        
        if response.status_code == 200:
            print("工作流执行成功")
            print(response.json())
            try:
                return response.json()
            except json.JSONDecodeError:
                print("响应内容解析失败")
                return {
                    "status": "error",
                    "message": "响应内容解析失败",
                    "raw_response": response.text
                }
        else:
            error_msg = f"工作流执行失败，状态码: {response.status_code}"
            print(error_msg)
            if hasattr(response, 'text'):
                print(f"错误详情: {response.text}")
            return {
                "status": "error",
                "message": error_msg,
                "error_details": response.text if hasattr(response, 'text') else None
            }
            
    except Exception as e:
        error_msg = f"执行工作流时发生错误: {str(e)}"
        print(error_msg)
        return {
            "status": "error",
            "message": error_msg
        }

def execute_workflow(file_path: str = "F:\\下载\\合同2.pdf"):
    """测试函数"""
    print("execute_workflow"+file_path)
    # 使用默认文件路径
    result = process_file(file_path)
    print("\n执行结果:"+result)
    try:
        # 尝试解析和格式化JSON输出
        result_dict = json.loads(result)
        # 提取关键信息
        if result_dict.get("status") == "error":
            print("execute_workflow状态: 失败")
            print(f"execute_workflow错误信息: {result_dict.get('message')}")
        else:
            print("execute_workflow状态: 成功")
            if "data" in result_dict:
                print("工作流输出:")
                data = result_dict["data"]
                result = data["outputs"]["text"].replace("```json", "").replace("```", "")

                print(json.loads(result))
                print(json.dumps(result, ensure_ascii=False, indent=2))
                outputs = data["outputs"]
                print("outputs:")
                print(outputs["text"])
            else:
                print('execute_workflow解析失败，未能获取 data信息')

        # 打印执行时间统计
        if "execution_time" in result_dict:
            exec_time = result_dict["execution_time"]
            if isinstance(exec_time, dict):
                print(f"\n执行时间统计:")
                print(f"总耗时: {exec_time['total']:.2f}秒")
                print(f"文件上传: {exec_time['upload']:.2f}秒")
                print(f"工作流执行: {exec_time['workflow']:.2f}秒")
            else:
                print(f"\n总耗时: {exec_time:.2f}秒")

        return result
    
    except json.JSONDecodeError:
        print("结果解析失败，原始输出:")
        print(result)

def main(args):

    result = execute_workflow(file_path="F:\\下载\\合同2.pdf") 
 
if __name__ == "__main__":
    main(args=None)

